using System;
using System.Collections.Generic;
using System.Linq;
using System.Security.Policy;
using Aliyun.OSS;
using RFS.BizLogic.PaiShi.Impl;
using RFS.BizLogic.utils;
using RFS.Domain.PaiShi;

namespace RFS.BizLogic.PaiShi.Ports.Adapters
{
    public class PriceManagerJiaoYiRecordsBasedAdapter : IPriceManagerPort
    {
        readonly Dictionary<string, IList<IProductPriceItem>> _cache =
            new Dictionary<string, IList<IProductPriceItem>>();

        public IProductPriceItem GetPrice(DateTime date, string supplier, string prodName, int length,
            bool smartChooseTheClosestPrice)
        {
            var prod = new Product(supplier, prodName, $"{length}");
            return GetPrice(date, prod, smartChooseTheClosestPrice);
        }

        public IProductPriceItem GetPrice(DateTime date, IProduct product,
            bool smartChooseTheClosestPrice = false)
        {
            var priceSet = GetPriceItems(date);
                var price=priceSet.FirstOrDefault(x => x.Product.Equals(product));

            if (price == null && smartChooseTheClosestPrice)
            {
                  price=priceSet.Where(x => x.Product.Name==product.Name    )
                      .OrderByDescending(x=>x.Price)
                      .FirstOrDefault();
                  if (price != null)
                  {
                      _log.Debug($"找不到产品 {product.Name} 的价格,系统偿试使用，同行产品价格【{price.Price:#.##}】.");
                      return price;
                  }
                
                _log.Debug($"找不到产品 {product.Name} 的价格,系统试回朔 7 天.");
                // do smart chose . do backtrace for 7 days
                for (int i = 0; i < 7; i++)
                {
                    var d = date.Date.AddDays(-(i+1) );
                    _log.Debug($"已加载 {d} 价格表 .");

                    var yestodayPrices = GetPriceItems(d)
                        .FirstOrDefault(x => x.Product.Equals(product));
                    if (yestodayPrices != null)
                    {
                        return yestodayPrices;
                    }
                }
            }

            if (price == null)
            {
                _log.Err(    new Exception($"价格没有找到。参数：{date},{product}"));
            }
              
            return price;
        }


        private IRepoPaiShi _repo;
        private ILog _log;

        public PriceManagerJiaoYiRecordsBasedAdapter(IRepoPaiShi repo, ILog log)
        {
            _repo = repo;
            _log = log;
        }

        public IEnumerable<IProductPriceItem> GetPriceItems(DateTime today)
        {
            var k = today.ToKey();
            if (_cache.ContainsKey(k)) return _cache[k];

            var rs = _repo.GetJiaoYiPrice(today)
                    .Select(x => 1.OfProductPriceItem(x as object))
                ;

            var res = rs.ToList();
            _cache[k] = res;
            return res;
        }
    }

    public static class ex
    {
        public static string ToKey(this DateTime date)
        {
            return date.ToString("yyyy-MM-dd");
        }
    }
}